// SPDX-License-Identifier: Mulan PSL v2
/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This software is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use std::ffi::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_ushort, c_void};

use once_cell::sync::Lazy;
use smallvec::smallvec;
use tracing::{debug, info};

use cudax::driver::*;
use xgpu_common::{
    api_name::ApiFuncName,
    ipc::message::{Argument, ArgumentFlag, Request},
};

use crate::{fault_guard::virt, hook::driver::DriverApi, hook_impl::native::dl, thread};

pub struct DriverApiImpl;

#[allow(unused_variables)]
impl DriverApi for DriverApiImpl {
    fn cuGetErrorString(&self, error: CUresult, p_str: *mut *const c_char) -> CUresult {
        unreachable!()
    }

    fn cuGetErrorName(&self, error: CUresult, p_str: *mut *const c_char) -> CUresult {
        unreachable!()
    }

    fn cuInit(&self, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuDriverGetVersion(&self, driver_version: *mut c_int) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGet(&self, device: *mut CUdevice, ordinal: c_int) -> CUresult {
        info!("[Hooked] api_name: cuDeviceGet");
        let req = Request::with_args(
            ApiFuncName::FuncCudeviceget as u64,
            smallvec![
                unsafe { Argument::from_mut_ptr(device, ArgumentFlag::ARG_OUT) },
                Argument::from_ref(&ordinal, ArgumentFlag::ARG_IN),
            ],
        );
        thread::context()
            .agent()
            .invoke_api::<CUresult>(req)
            .expect("call invoke_api failed")
    }

    fn cuDeviceGetCount(&self, count: *mut c_int) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetName(&self, name: *mut c_char, len: c_int, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetUuid(&self, uuid: *mut CUuuid, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetUuid_v2(&self, uuid: *mut CUuuid, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetLuid(
        &self,
        luid: *mut c_char,
        device_node_mask: *mut c_uint,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceTotalMem_v2(&self, bytes: *mut usize, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetTexture1DLinearMaxWidth(
        &self,
        max_width_in_elements: *mut usize,
        format: CUarray_format,
        num_channels: c_uint,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetAttribute(
        &self,
        pi: *mut c_int,
        attrib: CUdevice_attribute,
        dev: CUdevice,
    ) -> CUresult {
        info!("[Hooked] api_name: cuDeviceGetAttribute");
        let req = Request::with_args(
            ApiFuncName::FuncCudevicegetattribute as u64,
            smallvec![
                unsafe { Argument::from_mut_ptr(pi, ArgumentFlag::ARG_OUT) },
                Argument::from_ref(&attrib, ArgumentFlag::ARG_IN),
                Argument::from_ref(&dev, ArgumentFlag::ARG_IN),
            ],
        );
        thread::context()
            .agent()
            .invoke_api::<CUresult>(req)
            .expect("call invoke_api failed")
    }

    fn cuDeviceGetNvSciSyncAttributes(
        &self,
        nv_sci_sync_attr_list: *mut c_void,
        dev: CUdevice,
        flags: c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceSetMemPool(&self, dev: CUdevice, pool: CUmemoryPool) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetMemPool(&self, pool: *mut CUmemoryPool, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetDefaultMemPool(&self, pool_out: *mut CUmemoryPool, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetExecAffinitySupport(
        &self,
        pi: *mut c_int,
        type_: CUexecAffinityType,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuFlushGPUDirectRDMAWrites(
        &self,
        target: CUflushGPUDirectRDMAWritesTarget,
        scope: CUflushGPUDirectRDMAWritesScope,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetProperties(&self, prop: *mut CUdevprop, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceComputeCapability(
        &self,
        major: *mut c_int,
        minor: *mut c_int,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDevicePrimaryCtxRetain(&self, p_ctx: *mut CUcontext, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDevicePrimaryCtxRelease_v2(&self, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDevicePrimaryCtxSetFlags_v2(&self, dev: CUdevice, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuDevicePrimaryCtxGetState(
        &self,
        dev: CUdevice,
        flags: *mut c_uint,
        active: *mut c_int,
    ) -> CUresult {
        info!("[Hooked] api_name: cuDevicePrimaryCtxGetState");
        debug!(
            "ctxgetstate: dev:{}, flags:{}, active:{}",
            dev,
            unsafe { *flags },
            unsafe { *active }
        );
        let req = Request::with_args(
            ApiFuncName::FuncCudeviceprimaryctxgetstate as u64,
            smallvec![
                Argument::from_ref(&dev, ArgumentFlag::ARG_IN),
                unsafe { Argument::from_mut_ptr(flags, ArgumentFlag::ARG_OUT) },
                unsafe { Argument::from_mut_ptr(active, ArgumentFlag::ARG_OUT) },
            ],
        );
        let res = thread::context()
            .agent()
            .invoke_api::<CUresult>(req)
            .expect("call invoke_api failed");
        debug!(
            "ctxgetstate: dev:{}, flags:{}, active:{}, res:{}",
            dev,
            unsafe { *flags },
            unsafe { *active },
            res
        );
        res
    }

    fn cuDevicePrimaryCtxReset_v2(&self, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuCtxCreate_v2(&self, p_ctx: *mut CUcontext, flags: c_uint, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuCtxCreate_v3(
        &self,
        p_ctx: *mut CUcontext,
        params_array: *mut CUexecAffinityParam,
        num_params: c_int,
        flags: c_uint,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCtxDestroy_v2(&self, ctx: CUcontext) -> CUresult {
        unreachable!()
    }

    fn cuCtxPushCurrent_v2(&self, ctx: CUcontext) -> CUresult {
        unreachable!()
    }

    fn cuCtxPopCurrent_v2(&self, p_ctx: *mut CUcontext) -> CUresult {
        unreachable!()
    }

    fn cuCtxSetCurrent(&self, ctx: CUcontext) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetCurrent(&self, p_ctx: *mut CUcontext) -> CUresult {
        info!("[Hooked] api_name: cuCtxGetCurrent");
        let req = Request::with_args(
            ApiFuncName::FuncCuctxgetcurrent as u64,
            smallvec![unsafe { Argument::from_mut_ptr(p_ctx, ArgumentFlag::ARG_OUT) }],
        );
        thread::context()
            .agent()
            .invoke_api::<CUresult>(req)
            .expect("call invoke_api failed")
    }

    fn cuCtxGetDevice(&self, device: *mut CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetFlags(&self, flags: *mut c_uint) -> CUresult {
        unreachable!()
    }

    fn cuCtxSetFlags(&self, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetId(&self, ctx: CUcontext, ctx_id: *mut c_ulonglong) -> CUresult {
        unreachable!()
    }

    fn cuCtxSynchronize(&self) -> CUresult {
        unreachable!()
    }

    fn cuCtxSetLimit(&self, limit: CUlimit, value: usize) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetLimit(&self, pvalue: *mut usize, limit: CUlimit) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetCacheConfig(&self, p_config: *mut CUfunc_cache) -> CUresult {
        unreachable!()
    }

    fn cuCtxSetCacheConfig(&self, config: CUfunc_cache) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetApiVersion(&self, ctx: CUcontext, version: *mut c_uint) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetStreamPriorityRange(
        &self,
        least_priority: *mut c_int,
        greatest_priority: *mut c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCtxResetPersistingL2Cache(&self) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetExecAffinity(
        &self,
        p_exec_affinity: *mut CUexecAffinityParam,
        type_: CUexecAffinityType,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCtxAttach(&self, p_ctx: *mut CUcontext, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuCtxDetach(&self, ctx: CUcontext) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetSharedMemConfig(&self, p_config: *mut CUsharedconfig) -> CUresult {
        unreachable!()
    }

    fn cuCtxSetSharedMemConfig(&self, config: CUsharedconfig) -> CUresult {
        unreachable!()
    }

    fn cuModuleLoad(&self, module: *mut CUmodule, fname: *const c_char) -> CUresult {
        unreachable!()
    }

    fn cuModuleLoadData(&self, module: *mut CUmodule, image: *const c_void) -> CUresult {
        info!("[Hooked] api_name: cuModuleLoadData");
        unreachable!()
    }

    fn cuModuleLoadDataEx(
        &self,
        module: *mut CUmodule,
        image: *const c_void,
        num_options: c_uint,
        options: *mut CUjit_option,
        option_values: *mut *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuModuleLoadFatBinary(&self, module: *mut CUmodule, fat_cubin: *const c_void) -> CUresult {
        unreachable!()
    }

    fn cuModuleUnload(&self, hmod: CUmodule) -> CUresult {
        unreachable!()
    }

    fn cuModuleGetLoadingMode(&self, mode: *mut CUmoduleLoadingMode) -> CUresult {
        unreachable!()
    }

    fn cuModuleGetFunction(
        &self,
        hfunc: *mut CUfunction,
        hmod: CUmodule,
        name: *const c_char,
    ) -> CUresult {
        info!("[Hooked] api_name: cuModuleGetFunction");
        unreachable!()
    }

    fn cuModuleGetFunctionCount(&self, count: *mut c_uint, mod_: CUmodule) -> CUresult {
        unreachable!()
    }

    fn cuModuleEnumerateFunctions(
        &self,
        functions: *mut CUfunction,
        num_functions: c_uint,
        mod_: CUmodule,
    ) -> CUresult {
        unreachable!()
    }

    fn cuModuleGetGlobal_v2(
        &self,
        dptr: *mut CUdeviceptr,
        bytes: *mut usize,
        hmod: CUmodule,
        name: *const c_char,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLinkCreate_v2(
        &self,
        num_options: c_uint,
        options: *mut CUjit_option,
        option_values: *mut *mut c_void,
        state_out: *mut CUlinkState,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLinkAddData_v2(
        &self,
        state: CUlinkState,
        type_: CUjitInputType,
        data: *mut c_void,
        size: usize,
        name: *const c_char,
        num_options: c_uint,
        options: *mut CUjit_option,
        option_values: *mut *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLinkAddFile_v2(
        &self,
        state: CUlinkState,
        type_: CUjitInputType,
        path: *const c_char,
        num_options: c_uint,
        options: *mut CUjit_option,
        option_values: *mut *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLinkComplete(
        &self,
        state: CUlinkState,
        cubin_out: *mut *mut c_void,
        size_out: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLinkDestroy(&self, state: CUlinkState) -> CUresult {
        unreachable!()
    }

    fn cuModuleGetTexRef(
        &self,
        p_tex_ref: *mut CUtexref,
        hmod: CUmodule,
        name: *const c_char,
    ) -> CUresult {
        unreachable!()
    }

    fn cuModuleGetSurfRef(
        &self,
        p_surf_ref: *mut CUsurfref,
        hmod: CUmodule,
        name: *const c_char,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLibraryLoadData(
        &self,
        library: *mut CUlibrary,
        code: *const c_void,
        jit_options: *mut CUjit_option,
        jit_options_values: *mut *mut c_void,
        num_jit_options: c_uint,
        library_options: *mut CUlibraryOption,
        library_option_values: *mut *mut c_void,
        num_library_options: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLibraryLoadFromFile(
        &self,
        library: *mut CUlibrary,
        file_name: *const c_char,
        jit_options: *mut CUjit_option,
        jit_options_values: *mut *mut c_void,
        num_jit_options: c_uint,
        library_options: *mut CUlibraryOption,
        library_option_values: *mut *mut c_void,
        num_library_options: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLibraryUnload(&self, library: CUlibrary) -> CUresult {
        unreachable!()
    }

    fn cuLibraryGetKernel(
        &self,
        p_kernel: *mut CUkernel,
        library: CUlibrary,
        name: *const c_char,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLibraryGetKernelCount(&self, count: *mut c_uint, lib: CUlibrary) -> CUresult {
        unreachable!()
    }

    fn cuLibraryEnumerateKernels(
        &self,
        kernels: *mut CUkernel,
        num_kernels: c_uint,
        lib: CUlibrary,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLibraryGetModule(&self, p_mod: *mut CUmodule, library: CUlibrary) -> CUresult {
        unreachable!()
    }

    fn cuKernelGetFunction(&self, p_func: *mut CUfunction, kernel: CUkernel) -> CUresult {
        unreachable!()
    }

    fn cuLibraryGetGlobal(
        &self,
        dptr: *mut CUdeviceptr,
        bytes: *mut usize,
        library: CUlibrary,
        name: *const c_char,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLibraryGetManaged(
        &self,
        dptr: *mut CUdeviceptr,
        bytes: *mut usize,
        library: CUlibrary,
        name: *const c_char,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLibraryGetUnifiedFunction(
        &self,
        fptr: *mut *mut c_void,
        library: CUlibrary,
        symbol: *const c_char,
    ) -> CUresult {
        unreachable!()
    }

    fn cuKernelGetAttribute(
        &self,
        pi: *mut c_int,
        attrib: CUfunction_attribute,
        kernel: CUkernel,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuKernelSetAttribute(
        &self,
        attrib: CUfunction_attribute,
        val: c_int,
        kernel: CUkernel,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuKernelSetCacheConfig(
        &self,
        kernel: CUkernel,
        config: CUfunc_cache,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuKernelGetName(&self, name: *mut *const c_char, hfunc: CUkernel) -> CUresult {
        unreachable!()
    }

    fn cuKernelGetParamInfo(
        &self,
        kernel: CUkernel,
        param_index: usize,
        param_offset: *mut usize,
        param_size: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemGetInfo_v2(&self, free: *mut usize, total: *mut usize) -> CUresult {
        unreachable!()
    }

    fn cuMemAlloc_v2(&self, dptr: *mut CUdeviceptr, bytesize: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemAllocPitch_v2(
        &self,
        dptr: *mut CUdeviceptr,
        p_pitch: *mut usize,
        width_in_bytes: usize,
        height: usize,
        element_size_bytes: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemFree_v2(&self, dptr: CUdeviceptr) -> CUresult {
        unreachable!()
    }

    fn cuMemGetAddressRange_v2(
        &self,
        pbase: *mut CUdeviceptr,
        psize: *mut usize,
        dptr: CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemAllocHost_v2(&self, pp: *mut *mut c_void, bytesize: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemFreeHost(&self, p: *mut c_void) -> CUresult {
        unreachable!()
    }

    fn cuMemHostAlloc(&self, pp: *mut *mut c_void, bytesize: usize, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuMemHostGetDevicePointer_v2(
        &self,
        pdptr: *mut CUdeviceptr,
        p: *mut c_void,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemHostGetFlags(&self, pflags: *mut c_uint, p: *mut c_void) -> CUresult {
        unreachable!()
    }

    fn cuMemAllocManaged(
        &self,
        dptr: *mut CUdeviceptr,
        bytesize: usize,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceRegisterAsyncNotification(
        &self,
        device: CUdevice,
        callback_func: CUasyncCallback,
        user_data: *mut c_void,
        callback: *mut CUasyncCallbackHandle,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceUnregisterAsyncNotification(
        &self,
        device: CUdevice,
        callback: CUasyncCallbackHandle,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetByPCIBusId(&self, dev: *mut CUdevice, pci_bus_id: *const c_char) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetPCIBusId(&self, pci_bus_id: *mut c_char, len: c_int, dev: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuIpcGetEventHandle(&self, p_handle: *mut CUipcEventHandle, event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuIpcOpenEventHandle(&self, ph_event: *mut CUevent, handle: CUipcEventHandle) -> CUresult {
        unreachable!()
    }

    fn cuIpcGetMemHandle(&self, p_handle: *mut CUipcMemHandle, dptr: CUdeviceptr) -> CUresult {
        unreachable!()
    }

    fn cuIpcOpenMemHandle_v2(
        &self,
        pdptr: *mut CUdeviceptr,
        handle: CUipcMemHandle,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuIpcCloseMemHandle(&self, dptr: CUdeviceptr) -> CUresult {
        unreachable!()
    }

    fn cuMemHostRegister_v2(&self, p: *mut c_void, bytesize: usize, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuMemHostUnregister(&self, p: *mut c_void) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy(&self, dst: CUdeviceptr, src: CUdeviceptr, byte_count: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyPeer(
        &self,
        dst_device: CUdeviceptr,
        dst_context: CUcontext,
        src_device: CUdeviceptr,
        src_context: CUcontext,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyHtoD_v2(
        &self,
        dst_device: CUdeviceptr,
        src_host: *const c_void,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyDtoH_v2(
        &self,
        dst_host: *mut c_void,
        src_device: CUdeviceptr,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyDtoD_v2(
        &self,
        dst_device: CUdeviceptr,
        src_device: CUdeviceptr,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyDtoA_v2(
        &self,
        dst_array: CUarray,
        dst_offset: usize,
        src_device: CUdeviceptr,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyAtoD_v2(
        &self,
        dst_device: CUdeviceptr,
        src_array: CUarray,
        src_offset: usize,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyHtoA_v2(
        &self,
        dst_array: CUarray,
        dst_offset: usize,
        src_host: *const c_void,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyAtoH_v2(
        &self,
        dst_host: *mut c_void,
        src_array: CUarray,
        src_offset: usize,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyAtoA_v2(
        &self,
        dst_array: CUarray,
        dst_offset: usize,
        src_array: CUarray,
        src_offset: usize,
        byte_count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy2D_v2(&self, p_copy: *const CUDA_MEMCPY2D) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy2DUnaligned_v2(&self, p_copy: *const CUDA_MEMCPY2D) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy3D_v2(&self, p_copy: *const CUDA_MEMCPY3D) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy3DPeer(&self, p_copy: *const CUDA_MEMCPY3D_PEER) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyAsync(
        &self,
        dst: CUdeviceptr,
        src: CUdeviceptr,
        byte_count: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyPeerAsync(
        &self,
        dst_device: CUdeviceptr,
        dst_context: CUcontext,
        src_device: CUdeviceptr,
        src_context: CUcontext,
        byte_count: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyHtoDAsync_v2(
        &self,
        dst_device: CUdeviceptr,
        src_host: *const c_void,
        byte_count: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyDtoHAsync_v2(
        &self,
        dst_host: *mut c_void,
        src_device: CUdeviceptr,
        byte_count: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyDtoDAsync_v2(
        &self,
        dst_device: CUdeviceptr,
        src_device: CUdeviceptr,
        byte_count: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyHtoAAsync_v2(
        &self,
        dst_array: CUarray,
        dst_offset: usize,
        src_host: *const c_void,
        byte_count: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpyAtoHAsync_v2(
        &self,
        dst_host: *mut c_void,
        src_array: CUarray,
        src_offset: usize,
        byte_count: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy2DAsync_v2(&self, p_copy: *const CUDA_MEMCPY2D, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy3DAsync_v2(&self, p_copy: *const CUDA_MEMCPY3D, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuMemcpy3DPeerAsync(
        &self,
        p_copy: *const CUDA_MEMCPY3D_PEER,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD8_v2(&self, dst_device: CUdeviceptr, uc: c_uchar, n: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD16_v2(&self, dst_device: CUdeviceptr, us: c_ushort, n: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD32_v2(&self, dst_device: CUdeviceptr, ui: c_uint, n: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD2D8_v2(
        &self,
        dst_device: CUdeviceptr,
        dst_pitch: usize,
        uc: c_uchar,
        width: usize,
        height: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD2D16_v2(
        &self,
        dst_device: CUdeviceptr,
        dst_pitch: usize,
        us: c_ushort,
        width: usize,
        height: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD2D32_v2(
        &self,
        dst_device: CUdeviceptr,
        dst_pitch: usize,
        ui: c_uint,
        width: usize,
        height: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD8Async(
        &self,
        dst_device: CUdeviceptr,
        uc: c_uchar,
        n: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD16Async(
        &self,
        dst_device: CUdeviceptr,
        us: c_ushort,
        n: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD32Async(
        &self,
        dst_device: CUdeviceptr,
        ui: c_uint,
        n: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD2D8Async(
        &self,
        dst_device: CUdeviceptr,
        dst_pitch: usize,
        uc: c_uchar,
        width: usize,
        height: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD2D16Async(
        &self,
        dst_device: CUdeviceptr,
        dst_pitch: usize,
        us: c_ushort,
        width: usize,
        height: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemsetD2D32Async(
        &self,
        dst_device: CUdeviceptr,
        dst_pitch: usize,
        ui: c_uint,
        width: usize,
        height: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuArrayCreate_v2(
        &self,
        p_handle: *mut CUarray,
        p_allocate_array: *const CUDA_ARRAY_DESCRIPTOR,
    ) -> CUresult {
        unreachable!()
    }

    fn cuArrayGetDescriptor_v2(
        &self,
        p_array_descriptor: *mut CUDA_ARRAY_DESCRIPTOR,
        h_array: CUarray,
    ) -> CUresult {
        unreachable!()
    }

    fn cuArrayGetSparseProperties(
        &self,
        sparse_properties: *mut CUDA_ARRAY_SPARSE_PROPERTIES,
        array: CUarray,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMipmappedArrayGetSparseProperties(
        &self,
        sparse_properties: *mut CUDA_ARRAY_SPARSE_PROPERTIES,
        mipmap: CUmipmappedArray,
    ) -> CUresult {
        unreachable!()
    }

    fn cuArrayGetMemoryRequirements(
        &self,
        memory_requirements: *mut CUDA_ARRAY_MEMORY_REQUIREMENTS,
        array: CUarray,
        device: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMipmappedArrayGetMemoryRequirements(
        &self,
        memory_requirements: *mut CUDA_ARRAY_MEMORY_REQUIREMENTS,
        mipmap: CUmipmappedArray,
        device: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuArrayGetPlane(
        &self,
        p_plane_array: *mut CUarray,
        h_array: CUarray,
        plane_idx: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuArrayDestroy(&self, h_array: CUarray) -> CUresult {
        unreachable!()
    }

    fn cuArray3DCreate_v2(
        &self,
        p_handle: *mut CUarray,
        p_allocate_array: *const CUDA_ARRAY3D_DESCRIPTOR,
    ) -> CUresult {
        unreachable!()
    }

    fn cuArray3DGetDescriptor_v2(
        &self,
        p_array_descriptor: *mut CUDA_ARRAY3D_DESCRIPTOR,
        h_array: CUarray,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMipmappedArrayCreate(
        &self,
        p_handle: *mut CUmipmappedArray,
        p_mipmapped_array_desc: *const CUDA_ARRAY3D_DESCRIPTOR,
        num_mipmap_levels: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMipmappedArrayGetLevel(
        &self,
        p_level_array: *mut CUarray,
        h_mipmapped_array: CUmipmappedArray,
        level: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMipmappedArrayDestroy(&self, h_mipmapped_array: CUmipmappedArray) -> CUresult {
        unreachable!()
    }

    fn cuMemGetHandleForAddressRange(
        &self,
        handle: *mut c_void,
        dptr: CUdeviceptr,
        size: usize,
        handle_type: CUmemRangeHandleType,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemAddressReserve(
        &self,
        ptr: *mut CUdeviceptr,
        size: usize,
        alignment: usize,
        addr: CUdeviceptr,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemAddressFree(&self, ptr: CUdeviceptr, size: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemCreate(
        &self,
        handle: *mut CUmemGenericAllocationHandle,
        size: usize,
        prop: *const CUmemAllocationProp,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemRelease(&self, handle: CUmemGenericAllocationHandle) -> CUresult {
        unreachable!()
    }

    fn cuMemMap(
        &self,
        ptr: CUdeviceptr,
        size: usize,
        offset: usize,
        handle: CUmemGenericAllocationHandle,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemMapArrayAsync(
        &self,
        map_info_list: *mut CUarrayMapInfo,
        count: c_uint,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemUnmap(&self, ptr: CUdeviceptr, size: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemSetAccess(
        &self,
        ptr: CUdeviceptr,
        size: usize,
        desc: *const CUmemAccessDesc,
        count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemGetAccess(
        &self,
        flags: *mut c_ulonglong,
        location: *const CUmemLocation,
        ptr: CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemExportToShareableHandle(
        &self,
        shareable_handle: *mut c_void,
        handle: CUmemGenericAllocationHandle,
        handle_type: CUmemAllocationHandleType,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemImportFromShareableHandle(
        &self,
        handle: *mut CUmemGenericAllocationHandle,
        os_handle: *mut c_void,
        sh_handle_type: CUmemAllocationHandleType,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemGetAllocationGranularity(
        &self,
        granularity: *mut usize,
        prop: *const CUmemAllocationProp,
        option: CUmemAllocationGranularity_flags,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemGetAllocationPropertiesFromHandle(
        &self,
        prop: *mut CUmemAllocationProp,
        handle: CUmemGenericAllocationHandle,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemRetainAllocationHandle(
        &self,
        handle: *mut CUmemGenericAllocationHandle,
        addr: *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemFreeAsync(&self, dptr: CUdeviceptr, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuMemAllocAsync(
        &self,
        dptr: *mut CUdeviceptr,
        bytesize: usize,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolTrimTo(&self, pool: CUmemoryPool, min_bytes_to_keep: usize) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolSetAttribute(
        &self,
        pool: CUmemoryPool,
        attr: CUmemPool_attribute,
        value: *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolGetAttribute(
        &self,
        pool: CUmemoryPool,
        attr: CUmemPool_attribute,
        value: *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolSetAccess(
        &self,
        pool: CUmemoryPool,
        map: *const CUmemAccessDesc,
        count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolGetAccess(
        &self,
        flags: *mut CUmemAccess_flags,
        mem_pool: CUmemoryPool,
        location: *mut CUmemLocation,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolCreate(
        &self,
        pool: *mut CUmemoryPool,
        pool_props: *const CUmemPoolProps,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolDestroy(&self, pool: CUmemoryPool) -> CUresult {
        unreachable!()
    }

    fn cuMemAllocFromPoolAsync(
        &self,
        dptr: *mut CUdeviceptr,
        bytesize: usize,
        pool: CUmemoryPool,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolExportToShareableHandle(
        &self,
        handle_out: *mut c_void,
        pool: CUmemoryPool,
        handle_type: CUmemAllocationHandleType,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolImportFromShareableHandle(
        &self,
        pool_out: *mut CUmemoryPool,
        handle: *mut c_void,
        handle_type: CUmemAllocationHandleType,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolExportPointer(
        &self,
        share_data_out: *mut CUmemPoolPtrExportData,
        ptr: CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPoolImportPointer(
        &self,
        ptr_out: *mut CUdeviceptr,
        pool: CUmemoryPool,
        share_data: *mut CUmemPoolPtrExportData,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMulticastCreate(
        &self,
        mc_handle: *mut CUmemGenericAllocationHandle,
        prop: *const CUmulticastObjectProp,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMulticastAddDevice(
        &self,
        mc_handle: CUmemGenericAllocationHandle,
        dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMulticastBindMem(
        &self,
        mc_handle: CUmemGenericAllocationHandle,
        mc_offset: usize,
        mem_handle: CUmemGenericAllocationHandle,
        mem_offset: usize,
        size: usize,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMulticastBindAddr(
        &self,
        mc_handle: CUmemGenericAllocationHandle,
        mc_offset: usize,
        memptr: CUdeviceptr,
        size: usize,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMulticastUnbind(
        &self,
        mc_handle: CUmemGenericAllocationHandle,
        dev: CUdevice,
        mc_offset: usize,
        size: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMulticastGetGranularity(
        &self,
        granularity: *mut usize,
        prop: *const CUmulticastObjectProp,
        option: CUmulticastGranularity_flags,
    ) -> CUresult {
        unreachable!()
    }

    fn cuPointerGetAttribute(
        &self,
        data: *mut c_void,
        attribute: CUpointer_attribute,
        ptr: CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPrefetchAsync(
        &self,
        dev_ptr: CUdeviceptr,
        count: usize,
        dst_device: CUdevice,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemPrefetchAsync_v2(
        &self,
        dev_ptr: CUdeviceptr,
        count: usize,
        location: CUmemLocation,
        flags: c_uint,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemAdvise(
        &self,
        dev_ptr: CUdeviceptr,
        count: usize,
        advice: CUmem_advise,
        device: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemAdvise_v2(
        &self,
        dev_ptr: CUdeviceptr,
        count: usize,
        advice: CUmem_advise,
        location: CUmemLocation,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemRangeGetAttribute(
        &self,
        data: *mut c_void,
        data_size: usize,
        attribute: CUmem_range_attribute,
        dev_ptr: CUdeviceptr,
        count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuMemRangeGetAttributes(
        &self,
        data: *mut *mut c_void,
        data_sizes: *mut usize,
        attributes: *mut CUmem_range_attribute,
        num_attributes: usize,
        dev_ptr: CUdeviceptr,
        count: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuPointerSetAttribute(
        &self,
        value: *const c_void,
        attribute: CUpointer_attribute,
        ptr: CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuPointerGetAttributes(
        &self,
        num_attributes: c_uint,
        attributes: *mut CUpointer_attribute,
        data: *mut *mut c_void,
        ptr: CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamCreate(&self, ph_stream: *mut CUstream, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuStreamCreateWithPriority(
        &self,
        ph_stream: *mut CUstream,
        flags: c_uint,
        priority: c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetPriority(&self, h_stream: CUstream, priority: *mut c_int) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetFlags(&self, h_stream: CUstream, flags: *mut c_uint) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetId(&self, h_stream: CUstream, stream_id: *mut c_ulonglong) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetCtx(&self, h_stream: CUstream, p_ctx: *mut CUcontext) -> CUresult {
        unreachable!()
    }

    fn cuStreamWaitEvent(&self, h_stream: CUstream, h_event: CUevent, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuStreamAddCallback(
        &self,
        h_stream: CUstream,
        callback: CUstreamCallback,
        user_data: *mut c_void,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamBeginCapture_v2(&self, h_stream: CUstream, mode: CUstreamCaptureMode) -> CUresult {
        unreachable!()
    }

    fn cuStreamBeginCaptureToGraph(
        &self,
        h_stream: CUstream,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        dependency_data: *const CUgraphEdgeData,
        num_dependencies: usize,
        mode: CUstreamCaptureMode,
    ) -> CUresult {
        unreachable!()
    }

    fn cuThreadExchangeStreamCaptureMode(&self, mode: *mut CUstreamCaptureMode) -> CUresult {
        unreachable!()
    }

    fn cuStreamEndCapture(&self, h_stream: CUstream, ph_graph: *mut CUgraph) -> CUresult {
        unreachable!()
    }

    fn cuStreamIsCapturing(
        &self,
        h_stream: CUstream,
        capture_status: *mut CUstreamCaptureStatus,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetCaptureInfo_v2(
        &self,
        h_stream: CUstream,
        capture_status_out: *mut CUstreamCaptureStatus,
        id_out: *mut cuuint64_t,
        graph_out: *mut CUgraph,
        dependencies_out: *mut *const CUgraphNode,
        num_dependencies_out: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetCaptureInfo_v3(
        &self,
        h_stream: CUstream,
        capture_status_out: *mut CUstreamCaptureStatus,
        id_out: *mut cuuint64_t,
        graph_out: *mut CUgraph,
        dependencies_out: *mut *const CUgraphNode,
        edge_data_out: *mut *const CUgraphEdgeData,
        num_dependencies_out: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamUpdateCaptureDependencies(
        &self,
        h_stream: CUstream,
        dependencies: *mut CUgraphNode,
        num_dependencies: usize,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamUpdateCaptureDependencies_v2(
        &self,
        h_stream: CUstream,
        dependencies: *mut CUgraphNode,
        dependency_data: *const CUgraphEdgeData,
        num_dependencies: usize,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamAttachMemAsync(
        &self,
        h_stream: CUstream,
        dptr: CUdeviceptr,
        length: usize,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamQuery(&self, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuStreamSynchronize(&self, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuStreamDestroy_v2(&self, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuStreamCopyAttributes(&self, dst: CUstream, src: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetAttribute(
        &self,
        h_stream: CUstream,
        attr: CUstreamAttrID,
        value_out: *mut CUstreamAttrValue,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamSetAttribute(
        &self,
        h_stream: CUstream,
        attr: CUstreamAttrID,
        value: *const CUstreamAttrValue,
    ) -> CUresult {
        unreachable!()
    }

    fn cuEventCreate(&self, ph_event: *mut CUevent, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuEventRecord(&self, h_event: CUevent, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuEventRecordWithFlags(
        &self,
        h_event: CUevent,
        h_stream: CUstream,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuEventQuery(&self, h_event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuEventSynchronize(&self, h_event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuEventDestroy_v2(&self, h_event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuEventElapsedTime(
        &self,
        p_milliseconds: *mut f32,
        h_start: CUevent,
        h_end: CUevent,
    ) -> CUresult {
        unreachable!()
    }

    fn cuImportExternalMemory(
        &self,
        ext_mem_out: *mut CUexternalMemory,
        mem_handle_desc: *const CUDA_EXTERNAL_MEMORY_HANDLE_DESC,
    ) -> CUresult {
        unreachable!()
    }

    fn cuExternalMemoryGetMappedBuffer(
        &self,
        dev_ptr: *mut CUdeviceptr,
        ext_mem: CUexternalMemory,
        buffer_desc: *const CUDA_EXTERNAL_MEMORY_BUFFER_DESC,
    ) -> CUresult {
        unreachable!()
    }

    fn cuExternalMemoryGetMappedMipmappedArray(
        &self,
        mipmap: *mut CUmipmappedArray,
        ext_mem: CUexternalMemory,
        mipmap_desc: *const CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDestroyExternalMemory(&self, ext_mem: CUexternalMemory) -> CUresult {
        unreachable!()
    }

    fn cuImportExternalSemaphore(
        &self,
        ext_sem_out: *mut CUexternalSemaphore,
        sem_handle_desc: *const CUDA_EXTERNAL_SEMAPHORE_HANDLE_DESC,
    ) -> CUresult {
        unreachable!()
    }

    fn cuSignalExternalSemaphoresAsync(
        &self,
        ext_sem_array: *const CUexternalSemaphore,
        params_array: *const CUDA_EXTERNAL_SEMAPHORE_SIGNAL_PARAMS,
        num_ext_sems: c_uint,
        stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuWaitExternalSemaphoresAsync(
        &self,
        ext_sem_array: *const CUexternalSemaphore,
        params_array: *const CUDA_EXTERNAL_SEMAPHORE_WAIT_PARAMS,
        num_ext_sems: c_uint,
        stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDestroyExternalSemaphore(&self, ext_sem: CUexternalSemaphore) -> CUresult {
        unreachable!()
    }

    fn cuStreamWaitValue32_v2(
        &self,
        stream: CUstream,
        addr: CUdeviceptr,
        value: cuuint32_t,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamWaitValue64_v2(
        &self,
        stream: CUstream,
        addr: CUdeviceptr,
        value: cuuint64_t,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamWriteValue32_v2(
        &self,
        stream: CUstream,
        addr: CUdeviceptr,
        value: cuuint32_t,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamWriteValue64_v2(
        &self,
        stream: CUstream,
        addr: CUdeviceptr,
        value: cuuint64_t,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuStreamBatchMemOp_v2(
        &self,
        stream: CUstream,
        count: c_uint,
        param_array: *mut CUstreamBatchMemOpParams,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuFuncGetAttribute(
        &self,
        pi: *mut c_int,
        attrib: CUfunction_attribute,
        hfunc: CUfunction,
    ) -> CUresult {
        info!("[Hooked] api_name: cuFuncGetAttribute");

        let hfunc_usize = virt::handle_map(hfunc as *mut c_void).expect("handle_map failed")
            as CUfunction as usize;

        let req = Request::with_args(
            ApiFuncName::FuncCufuncgetattribute as u64,
            smallvec![
                unsafe { Argument::from_mut_ptr(pi, ArgumentFlag::ARG_OUT) },
                Argument::from_ref(&attrib, ArgumentFlag::ARG_IN),
                Argument::from_ref(&hfunc_usize, ArgumentFlag::ARG_IN | ArgumentFlag::ARG_VIRT),
            ],
        );
        thread::context()
            .agent()
            .invoke_api::<CUresult>(req)
            .expect("call invoke_api failed")
    }

    fn cuFuncSetAttribute(
        &self,
        hfunc: CUfunction,
        attrib: CUfunction_attribute,
        value: c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuFuncSetCacheConfig(&self, hfunc: CUfunction, config: CUfunc_cache) -> CUresult {
        unreachable!()
    }

    fn cuFuncGetModule(&self, hmod: *mut CUmodule, hfunc: CUfunction) -> CUresult {
        unreachable!()
    }

    fn cuFuncGetName(&self, name: *mut *const c_char, hfunc: CUfunction) -> CUresult {
        unreachable!()
    }

    fn cuFuncGetParamInfo(
        &self,
        func: CUfunction,
        param_index: usize,
        param_offset: *mut usize,
        param_size: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuFuncIsLoaded(&self, state: *mut CUfunctionLoadingState, function: CUfunction) -> CUresult {
        unreachable!()
    }

    fn cuFuncLoad(&self, function: CUfunction) -> CUresult {
        unreachable!()
    }

    fn cuLaunchKernel(
        &self,
        f: CUfunction,
        grid_dim_x: c_uint,
        grid_dim_y: c_uint,
        grid_dim_z: c_uint,
        block_dim_x: c_uint,
        block_dim_y: c_uint,
        block_dim_z: c_uint,
        shared_mem_bytes: c_uint,
        h_stream: CUstream,
        kernel_params: *mut *mut c_void,
        extra: *mut *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLaunchKernelEx(
        &self,
        config: *const CUlaunchConfig,
        f: CUfunction,
        kernel_params: *mut *mut c_void,
        extra: *mut *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLaunchCooperativeKernel(
        &self,
        f: CUfunction,
        grid_dim_x: c_uint,
        grid_dim_y: c_uint,
        grid_dim_z: c_uint,
        block_dim_x: c_uint,
        block_dim_y: c_uint,
        block_dim_z: c_uint,
        shared_mem_bytes: c_uint,
        h_stream: CUstream,
        kernel_params: *mut *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLaunchCooperativeKernelMultiDevice(
        &self,
        launch_params_list: *mut CUDA_LAUNCH_PARAMS,
        num_devices: c_uint,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLaunchHostFunc(
        &self,
        h_stream: CUstream,
        fn_: CUhostFn,
        user_data: *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuFuncSetBlockShape(&self, hfunc: CUfunction, x: c_int, y: c_int, z: c_int) -> CUresult {
        unreachable!()
    }

    fn cuFuncSetSharedSize(&self, hfunc: CUfunction, bytes: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuParamSetSize(&self, hfunc: CUfunction, numbytes: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuParamSeti(&self, hfunc: CUfunction, offset: c_int, value: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuParamSetf(&self, hfunc: CUfunction, offset: c_int, value: f32) -> CUresult {
        unreachable!()
    }

    fn cuParamSetv(
        &self,
        hfunc: CUfunction,
        offset: c_int,
        ptr: *mut c_void,
        numbytes: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuLaunch(&self, f: CUfunction) -> CUresult {
        unreachable!()
    }

    fn cuLaunchGrid(&self, f: CUfunction, grid_width: c_int, grid_height: c_int) -> CUresult {
        unreachable!()
    }

    fn cuLaunchGridAsync(
        &self,
        f: CUfunction,
        grid_width: c_int,
        grid_height: c_int,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuParamSetTexRef(&self, hfunc: CUfunction, texunit: c_int, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuFuncSetSharedMemConfig(&self, hfunc: CUfunction, config: CUsharedconfig) -> CUresult {
        unreachable!()
    }

    fn cuGraphCreate(&self, ph_graph: *mut CUgraph, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddKernelNode_v2(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        node_params: *const CUDA_KERNEL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphKernelNodeGetParams_v2(
        &self,
        h_node: CUgraphNode,
        node_params: *mut CUDA_KERNEL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphKernelNodeSetParams_v2(
        &self,
        h_node: CUgraphNode,
        node_params: *const CUDA_KERNEL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddMemcpyNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        copy_params: *const CUDA_MEMCPY3D,
        ctx: CUcontext,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphMemcpyNodeGetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *mut CUDA_MEMCPY3D,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphMemcpyNodeSetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *const CUDA_MEMCPY3D,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddMemsetNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        memset_params: *const CUDA_MEMSET_NODE_PARAMS,
        ctx: CUcontext,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphMemsetNodeGetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *mut CUDA_MEMSET_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphMemsetNodeSetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *const CUDA_MEMSET_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddHostNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        node_params: *const CUDA_HOST_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphHostNodeGetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *mut CUDA_HOST_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphHostNodeSetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *const CUDA_HOST_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddChildGraphNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        child_graph: CUgraph,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphChildGraphNodeGetGraph(
        &self,
        h_node: CUgraphNode,
        ph_graph: *mut CUgraph,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddEmptyNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddEventRecordNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        event: CUevent,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphEventRecordNodeGetEvent(
        &self,
        h_node: CUgraphNode,
        event_out: *mut CUevent,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphEventRecordNodeSetEvent(&self, h_node: CUgraphNode, event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddEventWaitNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        event: CUevent,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphEventWaitNodeGetEvent(
        &self,
        h_node: CUgraphNode,
        event_out: *mut CUevent,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphEventWaitNodeSetEvent(&self, h_node: CUgraphNode, event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddExternalSemaphoresSignalNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        node_params: *const CUDA_EXT_SEM_SIGNAL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExternalSemaphoresSignalNodeGetParams(
        &self,
        h_node: CUgraphNode,
        params_out: *mut CUDA_EXT_SEM_SIGNAL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExternalSemaphoresSignalNodeSetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *const CUDA_EXT_SEM_SIGNAL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddExternalSemaphoresWaitNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        node_params: *const CUDA_EXT_SEM_WAIT_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExternalSemaphoresWaitNodeGetParams(
        &self,
        h_node: CUgraphNode,
        params_out: *mut CUDA_EXT_SEM_WAIT_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExternalSemaphoresWaitNodeSetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *const CUDA_EXT_SEM_WAIT_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddBatchMemOpNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        node_params: *const CUDA_BATCH_MEM_OP_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphBatchMemOpNodeGetParams(
        &self,
        h_node: CUgraphNode,
        node_params_out: *mut CUDA_BATCH_MEM_OP_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphBatchMemOpNodeSetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *const CUDA_BATCH_MEM_OP_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecBatchMemOpNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        node_params: *const CUDA_BATCH_MEM_OP_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddMemAllocNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        node_params: *mut CUDA_MEM_ALLOC_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphMemAllocNodeGetParams(
        &self,
        h_node: CUgraphNode,
        params_out: *mut CUDA_MEM_ALLOC_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddMemFreeNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        dptr: CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphMemFreeNodeGetParams(
        &self,
        h_node: CUgraphNode,
        dptr_out: *mut CUdeviceptr,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGraphMemTrim(&self, device: CUdevice) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetGraphMemAttribute(
        &self,
        device: CUdevice,
        attr: CUgraphMem_attribute,
        value: *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceSetGraphMemAttribute(
        &self,
        device: CUdevice,
        attr: CUgraphMem_attribute,
        value: *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphClone(&self, ph_graph_clone: *mut CUgraph, original_graph: CUgraph) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeFindInClone(
        &self,
        ph_node: *mut CUgraphNode,
        h_original_node: CUgraphNode,
        h_cloned_graph: CUgraph,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeGetType(&self, h_node: CUgraphNode, type_: *mut CUgraphNodeType) -> CUresult {
        unreachable!()
    }

    fn cuGraphGetNodes(
        &self,
        h_graph: CUgraph,
        nodes: *mut CUgraphNode,
        num_nodes: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphGetRootNodes(
        &self,
        h_graph: CUgraph,
        root_nodes: *mut CUgraphNode,
        num_root_nodes: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphGetEdges(
        &self,
        h_graph: CUgraph,
        from: *mut CUgraphNode,
        to: *mut CUgraphNode,
        num_edges: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphGetEdges_v2(
        &self,
        h_graph: CUgraph,
        from: *mut CUgraphNode,
        to: *mut CUgraphNode,
        edge_data: *mut CUgraphEdgeData,
        num_edges: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeGetDependencies(
        &self,
        h_node: CUgraphNode,
        dependencies: *mut CUgraphNode,
        num_dependencies: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeGetDependencies_v2(
        &self,
        h_node: CUgraphNode,
        dependencies: *mut CUgraphNode,
        edge_data: *mut CUgraphEdgeData,
        num_dependencies: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeGetDependentNodes(
        &self,
        h_node: CUgraphNode,
        dependent_nodes: *mut CUgraphNode,
        num_dependent_nodes: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeGetDependentNodes_v2(
        &self,
        h_node: CUgraphNode,
        dependent_nodes: *mut CUgraphNode,
        edge_data: *mut CUgraphEdgeData,
        num_dependent_nodes: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddDependencies(
        &self,
        h_graph: CUgraph,
        from: *const CUgraphNode,
        to: *const CUgraphNode,
        num_dependencies: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddDependencies_v2(
        &self,
        h_graph: CUgraph,
        from: *const CUgraphNode,
        to: *const CUgraphNode,
        edge_data: *const CUgraphEdgeData,
        num_dependencies: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphRemoveDependencies(
        &self,
        h_graph: CUgraph,
        from: *const CUgraphNode,
        to: *const CUgraphNode,
        num_dependencies: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphRemoveDependencies_v2(
        &self,
        h_graph: CUgraph,
        from: *const CUgraphNode,
        to: *const CUgraphNode,
        edge_data: *const CUgraphEdgeData,
        num_dependencies: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphDestroyNode(&self, h_node: CUgraphNode) -> CUresult {
        unreachable!()
    }

    fn cuGraphInstantiateWithFlags(
        &self,
        ph_graph_exec: *mut CUgraphExec,
        h_graph: CUgraph,
        flags: c_ulonglong,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphInstantiateWithParams(
        &self,
        ph_graph_exec: *mut CUgraphExec,
        h_graph: CUgraph,
        instantiate_params: *mut CUDA_GRAPH_INSTANTIATE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecGetFlags(&self, h_graph_exec: CUgraphExec, flags: *mut cuuint64_t) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecKernelNodeSetParams_v2(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        node_params: *const CUDA_KERNEL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecMemcpyNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        copy_params: *const CUDA_MEMCPY3D,
        ctx: CUcontext,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecMemsetNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        memset_params: *const CUDA_MEMSET_NODE_PARAMS,
        ctx: CUcontext,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecHostNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        node_params: *const CUDA_HOST_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecChildGraphNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        child_graph: CUgraph,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecEventRecordNodeSetEvent(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        event: CUevent,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecEventWaitNodeSetEvent(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        event: CUevent,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecExternalSemaphoresSignalNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        node_params: *const CUDA_EXT_SEM_SIGNAL_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecExternalSemaphoresWaitNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        node_params: *const CUDA_EXT_SEM_WAIT_NODE_PARAMS,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeSetEnabled(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        is_enabled: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeGetEnabled(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        is_enabled: *mut c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphUpload(&self, h_graph_exec: CUgraphExec, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuGraphLaunch(&self, h_graph_exec: CUgraphExec, h_stream: CUstream) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecDestroy(&self, h_graph_exec: CUgraphExec) -> CUresult {
        unreachable!()
    }

    fn cuGraphDestroy(&self, h_graph: CUgraph) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecUpdate_v2(
        &self,
        h_graph_exec: CUgraphExec,
        h_graph: CUgraph,
        result_info: *mut CUgraphExecUpdateResultInfo,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphKernelNodeCopyAttributes(&self, dst: CUgraphNode, src: CUgraphNode) -> CUresult {
        unreachable!()
    }

    fn cuGraphKernelNodeGetAttribute(
        &self,
        h_node: CUgraphNode,
        attr: CUkernelNodeAttrID,
        value_out: *mut CUkernelNodeAttrValue,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphKernelNodeSetAttribute(
        &self,
        h_node: CUgraphNode,
        attr: CUkernelNodeAttrID,
        value: *const CUkernelNodeAttrValue,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphDebugDotPrint(
        &self,
        h_graph: CUgraph,
        path: *const c_char,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuUserObjectCreate(
        &self,
        object_out: *mut CUuserObject,
        ptr: *mut c_void,
        destroy: CUhostFn,
        initial_refcount: c_uint,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuUserObjectRetain(&self, object: CUuserObject, count: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuUserObjectRelease(&self, object: CUuserObject, count: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuGraphRetainUserObject(
        &self,
        graph: CUgraph,
        object: CUuserObject,
        count: c_uint,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphReleaseUserObject(
        &self,
        graph: CUgraph,
        object: CUuserObject,
        count: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddNode(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        num_dependencies: usize,
        node_params: *mut CUgraphNodeParams,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphAddNode_v2(
        &self,
        ph_graph_node: *mut CUgraphNode,
        h_graph: CUgraph,
        dependencies: *const CUgraphNode,
        dependency_data: *const CUgraphEdgeData,
        num_dependencies: usize,
        node_params: *mut CUgraphNodeParams,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphNodeSetParams(
        &self,
        h_node: CUgraphNode,
        node_params: *mut CUgraphNodeParams,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphExecNodeSetParams(
        &self,
        h_graph_exec: CUgraphExec,
        h_node: CUgraphNode,
        node_params: *mut CUgraphNodeParams,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphConditionalHandleCreate(
        &self,
        p_handle_out: *mut CUgraphConditionalHandle,
        h_graph: CUgraph,
        ctx: CUcontext,
        default_launch_value: c_uint,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuOccupancyMaxActiveBlocksPerMultiprocessor(
        &self,
        num_blocks: *mut c_int,
        func: CUfunction,
        block_size: c_int,
        dynamic_smem_size: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(
        &self,
        num_blocks: *mut c_int,
        func: CUfunction,
        block_size: c_int,
        dynamic_smem_size: usize,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuOccupancyMaxPotentialBlockSize(
        &self,
        min_grid_size: *mut c_int,
        block_size: *mut c_int,
        func: CUfunction,
        block_size_to_dynamic_smem_size: CUoccupancyB2DSize,
        dynamic_smem_size: usize,
        block_size_limit: c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuOccupancyMaxPotentialBlockSizeWithFlags(
        &self,
        min_grid_size: *mut c_int,
        block_size: *mut c_int,
        func: CUfunction,
        block_size_to_dynamic_smem_size: CUoccupancyB2DSize,
        dynamic_smem_size: usize,
        block_size_limit: c_int,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuOccupancyAvailableDynamicSMemPerBlock(
        &self,
        dynamic_smem_size: *mut usize,
        func: CUfunction,
        num_blocks: c_int,
        block_size: c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuOccupancyMaxPotentialClusterSize(
        &self,
        cluster_size: *mut c_int,
        func: CUfunction,
        config: *const CUlaunchConfig,
    ) -> CUresult {
        unreachable!()
    }

    fn cuOccupancyMaxActiveClusters(
        &self,
        num_clusters: *mut c_int,
        func: CUfunction,
        config: *const CUlaunchConfig,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetArray(&self, h_tex_ref: CUtexref, h_array: CUarray, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetMipmappedArray(
        &self,
        h_tex_ref: CUtexref,
        h_mipmapped_array: CUmipmappedArray,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetAddress_v2(
        &self,
        byte_offset: *mut usize,
        h_tex_ref: CUtexref,
        dptr: CUdeviceptr,
        bytes: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetAddress2D_v3(
        &self,
        h_tex_ref: CUtexref,
        desc: *const CUDA_ARRAY_DESCRIPTOR,
        dptr: CUdeviceptr,
        pitch: usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetFormat(
        &self,
        h_tex_ref: CUtexref,
        fmt: CUarray_format,
        num_packed_components: c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetAddressMode(
        &self,
        h_tex_ref: CUtexref,
        dim: c_int,
        am: CUaddress_mode,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetFilterMode(&self, h_tex_ref: CUtexref, fm: CUfilter_mode) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetMipmapFilterMode(&self, h_tex_ref: CUtexref, fm: CUfilter_mode) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetMipmapLevelBias(&self, h_tex_ref: CUtexref, bias: f32) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetMipmapLevelClamp(
        &self,
        h_tex_ref: CUtexref,
        min_mipmap_level_clamp: f32,
        max_mipmap_level_clamp: f32,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetMaxAnisotropy(&self, h_tex_ref: CUtexref, max_aniso: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetBorderColor(&self, h_tex_ref: CUtexref, p_border_color: *mut f32) -> CUresult {
        unreachable!()
    }

    fn cuTexRefSetFlags(&self, h_tex_ref: CUtexref, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetAddress_v2(&self, pdptr: *mut CUdeviceptr, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetArray(&self, ph_array: *mut CUarray, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetMipmappedArray(
        &self,
        ph_mipmapped_array: *mut CUmipmappedArray,
        h_tex_ref: CUtexref,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetAddressMode(
        &self,
        pam: *mut CUaddress_mode,
        h_tex_ref: CUtexref,
        dim: c_int,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetFilterMode(&self, pfm: *mut CUfilter_mode, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetFormat(
        &self,
        p_format: *mut CUarray_format,
        pnum_channels: *mut c_int,
        h_tex_ref: CUtexref,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetMipmapFilterMode(
        &self,
        pfm: *mut CUfilter_mode,
        h_tex_ref: CUtexref,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetMipmapLevelBias(&self, pbias: *mut f32, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetMipmapLevelClamp(
        &self,
        p_min_mipmap_level_clamp: *mut f32,
        p_max_mipmap_level_clamp: *mut f32,
        h_tex_ref: CUtexref,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetMaxAnisotropy(&self, p_max_aniso: *mut c_int, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetBorderColor(&self, p_border_color: *mut f32, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefGetFlags(&self, pflags: *mut c_uint, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefCreate(&self, p_tex_ref: *mut CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuTexRefDestroy(&self, h_tex_ref: CUtexref) -> CUresult {
        unreachable!()
    }

    fn cuSurfRefSetArray(
        &self,
        h_surf_ref: CUsurfref,
        h_array: CUarray,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuSurfRefGetArray(&self, ph_array: *mut CUarray, h_surf_ref: CUsurfref) -> CUresult {
        unreachable!()
    }

    fn cuTexObjectCreate(
        &self,
        p_tex_object: *mut CUtexObject,
        p_res_desc: *const CUDA_RESOURCE_DESC,
        p_tex_desc: *const CUDA_TEXTURE_DESC,
        p_res_view_desc: *const CUDA_RESOURCE_VIEW_DESC,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexObjectDestroy(&self, tex_object: CUtexObject) -> CUresult {
        unreachable!()
    }

    fn cuTexObjectGetResourceDesc(
        &self,
        p_res_desc: *mut CUDA_RESOURCE_DESC,
        tex_object: CUtexObject,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexObjectGetTextureDesc(
        &self,
        p_tex_desc: *mut CUDA_TEXTURE_DESC,
        tex_object: CUtexObject,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTexObjectGetResourceViewDesc(
        &self,
        p_res_view_desc: *mut CUDA_RESOURCE_VIEW_DESC,
        tex_object: CUtexObject,
    ) -> CUresult {
        unreachable!()
    }

    fn cuSurfObjectCreate(
        &self,
        p_surf_object: *mut CUsurfObject,
        p_res_desc: *const CUDA_RESOURCE_DESC,
    ) -> CUresult {
        unreachable!()
    }

    fn cuSurfObjectDestroy(&self, surf_object: CUsurfObject) -> CUresult {
        unreachable!()
    }

    fn cuSurfObjectGetResourceDesc(
        &self,
        p_res_desc: *mut CUDA_RESOURCE_DESC,
        surf_object: CUsurfObject,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTensorMapEncodeTiled(
        &self,
        tensor_map: *mut CUtensorMap,
        tensor_data_type: CUtensorMapDataType,
        tensor_rank: cuuint32_t,
        global_address: *mut c_void,
        global_dim: *const cuuint64_t,
        global_strides: *const cuuint64_t,
        box_dim: *const cuuint32_t,
        element_strides: *const cuuint32_t,
        interleave: CUtensorMapInterleave,
        swizzle: CUtensorMapSwizzle,
        l2_promotion: CUtensorMapL2promotion,
        oob_fill: CUtensorMapFloatOOBfill,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTensorMapEncodeIm2col(
        &self,
        tensor_map: *mut CUtensorMap,
        tensor_data_type: CUtensorMapDataType,
        tensor_rank: cuuint32_t,
        global_address: *mut c_void,
        global_dim: *const cuuint64_t,
        global_strides: *const cuuint64_t,
        pixel_box_lower_corner: *const c_int,
        pixel_box_upper_corner: *const c_int,
        channels_per_pixel: cuuint32_t,
        pixels_per_column: cuuint32_t,
        element_strides: *const cuuint32_t,
        interleave: CUtensorMapInterleave,
        swizzle: CUtensorMapSwizzle,
        l2_promotion: CUtensorMapL2promotion,
        oob_fill: CUtensorMapFloatOOBfill,
    ) -> CUresult {
        unreachable!()
    }

    fn cuTensorMapReplaceAddress(
        &self,
        tensor_map: *mut CUtensorMap,
        global_address: *mut c_void,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDeviceCanAccessPeer(
        &self,
        can_access_peer: *mut c_int,
        dev: CUdevice,
        peer_dev: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCtxEnablePeerAccess(&self, peer_context: CUcontext, flags: c_uint) -> CUresult {
        unreachable!()
    }

    fn cuCtxDisablePeerAccess(&self, peer_context: CUcontext) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetP2PAttribute(
        &self,
        value: *mut c_int,
        attrib: CUdevice_P2PAttribute,
        src_device: CUdevice,
        dst_device: CUdevice,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphicsUnregisterResource(&self, resource: CUgraphicsResource) -> CUresult {
        unreachable!()
    }

    fn cuGraphicsSubResourceGetMappedArray(
        &self,
        p_array: *mut CUarray,
        resource: CUgraphicsResource,
        array_index: c_uint,
        mip_level: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphicsResourceGetMappedMipmappedArray(
        &self,
        p_mipmapped_array: *mut CUmipmappedArray,
        resource: CUgraphicsResource,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphicsResourceGetMappedPointer_v2(
        &self,
        p_dev_ptr: *mut CUdeviceptr,
        p_size: *mut usize,
        resource: CUgraphicsResource,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphicsResourceSetMapFlags_v2(
        &self,
        resource: CUgraphicsResource,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphicsMapResources(
        &self,
        count: c_uint,
        resources: *mut CUgraphicsResource,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGraphicsUnmapResources(
        &self,
        count: c_uint,
        resources: *mut CUgraphicsResource,
        h_stream: CUstream,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGetProcAddress_v2(
        &self,
        symbol: *const c_char,
        pfn: *mut *mut c_void,
        cuda_version: c_int,
        flags: cuuint64_t,
        symbol_status: *mut CUdriverProcAddressQueryResult,
    ) -> CUresult {
        type CuGetProcAddressV2Fn = unsafe extern "C" fn(
            symbol: *const c_char,
            pfn: *mut *mut c_void,
            cuda_version: i32,
            flags: cuuint64_t,
            symbol_status: *mut CUdriverProcAddressQueryResult,
        ) -> CUresult;

        static GLOBAL_CUGETPROCADDRESSV2: Lazy<CuGetProcAddressV2Fn> = Lazy::new(|| {
            let ptr = dl::find_original_symbol("cuGetProcAddress_v2")
                .expect("FATAL: Failed to get original function");
            debug!("cuGetProcAddress_v2: {:#?}", ptr);

            // SAFETY: The caller upholds the contract specified in the documentation.
            // This is the standard way to convert a data pointer to a function pointer or other type.
            unsafe { ptr.cast() }
        });

        info!("[hooked] cuGetProcAddress_v2 (from src ?)");
        let res =
            unsafe { GLOBAL_CUGETPROCADDRESSV2(symbol, pfn, cuda_version, flags, symbol_status) };
        debug!("real--cuGetProcAddress_v2 (return res: {})", res);
        res
    }

    fn cuCoredumpGetAttribute(
        &self,
        attrib: CUcoredumpSettings,
        value: *mut c_void,
        size: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCoredumpGetAttributeGlobal(
        &self,
        attrib: CUcoredumpSettings,
        value: *mut c_void,
        size: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCoredumpSetAttribute(
        &self,
        attrib: CUcoredumpSettings,
        value: *mut c_void,
        size: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCoredumpSetAttributeGlobal(
        &self,
        attrib: CUcoredumpSettings,
        value: *mut c_void,
        size: *mut usize,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGetExportTable(
        &self,
        pp_export_table: *mut *const c_void,
        p_export_table_id: *const CUuuid,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGreenCtxCreate(
        &self,
        ph_ctx: *mut CUgreenCtx,
        desc: CUdevResourceDesc,
        dev: CUdevice,
        flags: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGreenCtxDestroy(&self, h_ctx: CUgreenCtx) -> CUresult {
        unreachable!()
    }

    fn cuCtxFromGreenCtx(&self, p_context: *mut CUcontext, h_ctx: CUgreenCtx) -> CUresult {
        unreachable!()
    }

    fn cuDeviceGetDevResource(
        &self,
        device: CUdevice,
        resource: *mut CUdevResource,
        type_: CUdevResourceType,
    ) -> CUresult {
        unreachable!()
    }

    fn cuCtxGetDevResource(
        &self,
        h_ctx: CUcontext,
        resource: *mut CUdevResource,
        type_: CUdevResourceType,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGreenCtxGetDevResource(
        &self,
        h_ctx: CUgreenCtx,
        resource: *mut CUdevResource,
        type_: CUdevResourceType,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDevSmResourceSplitByCount(
        &self,
        result: *mut CUdevResource,
        nb_groups: *mut c_uint,
        input: *const CUdevResource,
        remaining: *mut CUdevResource,
        useflags: c_uint,
        min_count: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuDevResourceGenerateDesc(
        &self,
        ph_desc: *mut CUdevResourceDesc,
        resources: *mut CUdevResource,
        nb_resources: c_uint,
    ) -> CUresult {
        unreachable!()
    }

    fn cuGreenCtxRecordEvent(&self, h_ctx: CUgreenCtx, h_event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuGreenCtxWaitEvent(&self, h_ctx: CUgreenCtx, h_event: CUevent) -> CUresult {
        unreachable!()
    }

    fn cuStreamGetGreenCtx(&self, h_stream: CUstream, ph_ctx: *mut CUgreenCtx) -> CUresult {
        unreachable!()
    }
}
